package bancosys.tec.persist.persister;

import java.util.Set;

import org.hibernate.SessionFactory;

import bancosys.tec.persist.Persistable;
import bancosys.tec.persist.audit.AuditManager;
import bancosys.tec.persist.persister.listener.PersisterListener;
import bancosys.tec.persist.validator.Validator;
import bancosys.tec.persist.validator.ValidatorFactory;

/**
 * @author Frank Cara
 * @param <T> o persistível
 */
public interface Persister<T extends Persistable> {

    /**
     * Devolve o validador do bean.
     * 
     * @return o validador do bean.
     */
    Validator<T> getValidator();

    /**
     * Devolve o gerenciador de auditoria.
     * 
     * @return o gerenciador de auditoria.
     */
    AuditManager getAuditManager();

    /**
     * Devolve a session factory.
     * 
     * @return a session factory.
     */
    SessionFactory getSessionFactory();

    /**
     * Salva um objeto na base de dados. Se for um novo objeto, ele será inserido. Se for um objeto existente, ele será atualizado.
     */
    void save();

    /**
     * Além de salvar a entidade, como em {@link Persister#save()}, se a entidade for do tipo
     * {@link bancosys.tec.persist.authorization.AuthorizableActionAware}, salva a ação que causou o bean ir para autorização.
     * 
     * @param authAction ação que está enviando a entidade para autorização.
     */
    void save(Object authAction);

    /**
     * Remove um objeto da base de dados.
     */
    void remove();

    /**
     * Define a session factory.
     * 
     * @param sessionFactory session factory.
     */
    void setSessionFactory(SessionFactory sessionFactory);

    /**
     * Define a validator factory.
     * 
     * @param validatorFactory session factory.
     */
    void setValidatorFactory(ValidatorFactory validatorFactory);

    /**
     * Define o bean que sera persistido por esse persiter.
     * 
     * @param bean o bean que sera persistido por esse persiter.
     */
    void setTarget(T bean);

    /**
     * Define o gerenciador de auditoria.
     * 
     * @param auditManager o gerenciador de auditoria.
     */
    void setAuditManager(AuditManager auditManager);

    /**
     * Devolve <code>true</code> se o bean sendo tratado deve ser autorizado, <code>false</code> caso contrário.
     * 
     * @return <code>true</code> se o bean sendo tratado deve ser autorizado, <code>false</code> caso contrário.
     */
    boolean isAuthorizable();

    /**
     * Adiona uma lista de listener a este persister.
     * 
     * @param set Lista de listener a ser adicionado para este persister.
     */
    void setListeners(Set<PersisterListener<T>> set);
}
